from pathlib import Path
from pyecharts import options as opts
from pyecharts.charts import WordCloud
from pyecharts.globals import SymbolType

class KeywordCloudGenerator:
    """关键词云图生成器"""
    
    def __init__(self, min_font_size=12, max_font_size=60):
        """
        初始化词云图生成器
        
        参数:
            min_font_size: int - 最小字体大小
            max_font_size: int - 最大字体大小
        """
        self.min_font_size = min_font_size
        self.max_font_size = max_font_size
        
    def _preprocess_data(self, data, min_frequency=1, top_n=None):
        """
        预处理关键词数据
        
        参数:
            data: Dict[str, int] - 关键词及其频率
            min_frequency: int - 最小频率阈值
            top_n: int - 只保留前N个高频词
        """
        # 过滤并转换数据
        word_pairs = [
            (word, count) for word, count in data.items()
            if count >= min_frequency
        ]
        
        # 按频率降序排序
        word_pairs.sort(key=lambda x: x[1], reverse=True)
        
        # 截取前N个
        if top_n:
            word_pairs = word_pairs[:top_n]
            
        return word_pairs
    
    def generate(self, data, year, save_path, title=None, min_frequency=1, top_n=100):
        """
        生成词云图
        
        参数:
            data: Dict[str, int] - 关键词及其频率
            year: int - 年份
            save_path: str - 保存路径
            title: str - 自定义标题
            min_frequency: int - 最小频率阈值
            top_n: int - 只显示前N个高频词
            
        异常:
            ValueError: 当数据无效或年份无效时
            OSError: 当保存路径无效时
        """
        try:
            # 验证年份
            if not isinstance(year, int) or year < 0:
                raise ValueError(f"无效的年份: {year}")
            
            # 验证数据
            if not data:
                raise ValueError("没有满足条件的关键词数据")
            
            # 确保输出目录存在
            save_path = Path(save_path)
            save_path.parent.mkdir(parents=True, exist_ok=True)
            
            # 数据预处理
            word_pairs = self._preprocess_data(data, min_frequency, top_n)
            
            if not word_pairs:
                raise ValueError("没有满足条件的关键词数据")
            
            # 创建词云图实例
            cloud = WordCloud(
                init_opts=opts.InitOpts(
                    width="600px",
                    height="400px",
                    bg_color="#ffffff",
                    page_title=f"{year}年专利关键词云图"
                )
            )
            
            # 添加数据
            cloud.add(
                series_name="关键词频率",
                data_pair=word_pairs,
                word_size_range=[self.min_font_size, self.max_font_size],
                textstyle_opts=opts.TextStyleOpts(
                    font_family="Microsoft YaHei",
                    font_weight="bold"
                ),
                shape=SymbolType.DIAMOND,
                rotate_step=45  # 允许45度角旋转
            )
            
            # 设置全局配置
            cloud.set_global_opts(
                title_opts=opts.TitleOpts(
                    is_show=False,
                    title=title or f"{year}年专利关键词分布",
                    subtitle=f"统计时间：{year}年",
                    pos_left="center",
                    title_textstyle_opts=opts.TextStyleOpts(
                        font_size=24,
                        color="#000"
                    )
                ),
                tooltip_opts=opts.TooltipOpts(
                    trigger="item",
                    formatter="{b}: 出现{c}次",
                    textstyle_opts=opts.TextStyleOpts(
                        font_size=14
                    )
                )
            )
            
            # 渲染词云图
            cloud.render(save_path)
            return save_path
            
        except Exception as e:
            print(f"Error details: {str(e)}")
            raise 